using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using MacomberMap.Common.Internals;
using System.Drawing;
using System.Drawing.Imaging;
using MacomberMap.Common.User_Interfaces.One_Lines;
using MacomberMap.Common.Database_Interface;
using MacomberMap.Common.User_Interfaces.Components;
using MacomberMap.Common.Types;

namespace MacomberMap.Common.Components
{
    /// <summary>
    /// This class holds the information on a one-line
    /// </summary>
    [MM_Serializable_Target(MM_Serializable_Target.enumTargetType.TypeCollection)]
    public class MM_OneLine
    {
        #region Variable declarations
        /// <summary>The XML configuration for the element</summary>
        [MM_Serializable_Target(MM_Serializable_Target.enumTargetType.TypeCollection)]
        public XmlElement One_Line;

        /// <summary>The associated element (substation or contingency definition)</summary>
        [MM_Serializable_Target(MM_Serializable_Target.enumTargetType.TypeCollection)]
        public MM_Element Base_Element;

        /// <summary>
        /// Return the name of the one-line element
        /// </summary>
        [MM_Serializable_Target(MM_Serializable_Target.enumTargetType.TypeCollection)]
        public String Name
        {
            get { return Base_Element.Name; }
        }

        /// <summary>Retrieve an image of the one-line</summary>
        [MM_Serializable_Target(MM_Serializable_Target.enumTargetType.TypeCollection)]
        public Image OneLineImage
        {
            get
            {              
                MM_Element TempRemove = null;
                if (MM_Repository.TEIDs.ContainsKey(Base_Element.TEID) && MM_Repository.TEIDs[Base_Element.TEID] != Base_Element)
                {
                    TempRemove = MM_Repository.TEIDs[Base_Element.TEID];
                    MM_Repository.TEIDs.Remove(Base_Element.TEID);
                }

                if (!MM_Repository.TEIDs.ContainsKey(Base_Element.TEID))
                    MM_Repository.TEIDs.Add(Base_Element.TEID, Base_Element);


                Image OutImage;
                using (MM_OneLine_Viewer OutLine = new MM_OneLine_Viewer(One_Line, null))
                    OutImage = OutLine.OneLineImage;

                if (TempRemove != null)
                {
                    MM_Repository.TEIDs.Remove(TempRemove.TEID);
                    MM_Repository.TEIDs.Add(TempRemove.TEID, TempRemove);
                }

                return OutImage;

                /*

                Dictionary<MM_Element, bool> ImportedElems = new Dictionary<MM_Element, bool>();               


                    AddElement(ImportedElems, BaseElement.Attributes["Base_Element"].Value, BaseElement.Attributes["Type"].Value, BaseElement.Attributes["Name"].Value, "Other KV");

                    foreach (XmlElement xElem in BaseElement["Elements"].ChildNodes)
                    {
                        AddElement(ImportedElems, xElem.Attributes["BaseElement"].Value, xElem.Name, xElem.Attributes["BaseName"].Value, (xElem.HasAttribute("KVLevel") ? xElem.Attributes["KVLevel"].Value : "Other KV"));
                        foreach (XmlElement xWinding in xElem.ChildNodes)
                            if (xWinding.Name == "Winding")
                                AddElement(ImportedElems, xWinding.Attributes["BaseElement"].Value, "TransformerWinding", xElem.Attributes["BaseName"].Value, xWinding.Attributes["KVLevel"].Value);
                    }

                foreach (XmlElement xElem in BaseElement["Nodes"].ChildNodes)
                {
                    if (xElem.Name == "Node")
                        AddElement(ImportedElems, xElem.Attributes["BaseElement"].Value, xElem.Name, xElem.Attributes["BaseName"].Value, xElem.Attributes["KVLevel"].Value);
                    foreach (XmlElement xPricingVector in xElem.ChildNodes)
                        if (xPricingVector.Name == "PricingVector")
                            AddElement(ImportedElems, xPricingVector.Attributes["BaseElement"].Value, xPricingVector.Name, xPricingVector.Attributes["BaseName"].Value, xElem.Attributes["KVLevel"].Value);
                }
                Image OutImage;
                using (MM_OneLine_Viewer OutLine = new MM_OneLine_Viewer(BaseElement, null, null, null))
                    OutImage = OutLine.OneLineImage;

                //Now, remove all elements that were temporarily created
                foreach (KeyValuePair<MM_Element, bool> kvp in ImportedElems)
                    if (kvp.Value)
                        MM_Repository.TEIDs.Remove(kvp.Key.TEID);
                return OutImage;*/
            }
        }

        /// <summary>
        /// Determine if an element exists in the repository. If not, add it in and flag it as temporary.
        /// </summary>
        /// <param name="ImportedElems">The imported elements</param>
        /// <param name="TEID">The TEID of the element</param>
        /// <param name="Type">The type of the element</param>
        /// <param name="Name">The name of the element</param>
        /// <param name="KVLevel">The KV level of the element</param>
        private void AddElement(Dictionary<MM_Element, bool> ImportedElems, String TEID, String Type, String Name, String KVLevel)
        {
            UInt64 OutTEID = Convert.ToUInt64(TEID);
            if (MM_Repository.TEIDs.ContainsKey(OutTEID) && MM_Repository.TEIDs[OutTEID].ElemType.Name == Type)
                ImportedElems.Add(MM_Repository.TEIDs[OutTEID], false);
            else
            {
                MM_Element NewElem = MM_Element.CreateElement(MM_Overall_Display.FindElementType(Type));                
                NewElem.TEID = OutTEID;
                NewElem.ElemType = MM_Overall_Display.FindElementType(Type);
                NewElem.Name = Name;
                NewElem.KVLevel = MM_Overall_Display.FindKVLevel(KVLevel);
                ImportedElems.Add(NewElem, true);
                MM_Repository.TEIDs.Remove(NewElem.TEID);
                MM_Repository.TEIDs.Add(NewElem.TEID, NewElem);
            }
        }
        #endregion

        #region Initialization
        /// <summary>
        /// Initialize a new MM One-line with an XML element
        /// </summary>
        /// <param name="xElement">The XML definition of the oneline</param>
        public MM_OneLine(XmlElement xElement)
        {
            this.One_Line = xElement;
            MM_Serializable.ReadXml(xElement, this);

            if (!String.IsNullOrEmpty(xElement.InnerText))
            {
                XmlDocument HolderDoc = new XmlDocument();
                HolderDoc.LoadXml(xElement.InnerText);
                this.One_Line = HolderDoc.DocumentElement;
            }
        }

        /// <summary>
        /// Initialize a new MM One-line with an XML element
        /// </summary>
        /// <param name="xElem">The XML definition of the oneline</param>
        public MM_OneLine(String xElem)
        {
            if (!String.IsNullOrEmpty(xElem))
            {
                XmlDocument HolderDoc = new XmlDocument();
                HolderDoc.LoadXml(xElem);
                this.One_Line = HolderDoc.DocumentElement;
                MM_Serializable.ReadXml(this.One_Line, this);                
            }
        }
        #endregion

        
    }
}
